import pandas as pd
import numpy as np
import datetime
import base64
from elasticsearch import Elasticsearch
from es_config import ES_IP, get_now_date

es = Elasticsearch(ES_IP)
service_df_head = ['service_apdex', 'service_resp_time', 'service_sla', 'service_cpm']
print(es)

def time_transform(time_bucket, minutes):
    time_bucket = str(time_bucket)
    index = False
    if len(time_bucket) == 12:
        index = int(time_bucket[8:10]) * 60 + int(time_bucket[10:])
        index = index - minutes
    return index


def get_service_attr(source, service_dict, index, date, tag):    #处理一个source
    minutes = date.hour * 60 + date.minute
    service_id = source['entity_id']
    # print(service_id)
    try:
        service_id = str(base64.b64decode(service_id.encode('utf-8')), encoding='utf-8')
    except:
        service_id = str(base64.b64decode(service_id[:-2].encode('utf-8')), encoding='utf-8')
    time_bucket = time_transform(source['time_bucket'], minutes)
    if service_df_head[index] == 'service_apdex':
        value = source['value'] / 10000
    elif service_df_head[index] == 'service_sla':
        value = source['percentage'] / 100
    else:
        value = source['value']
    rows = 0
    if tag == 'start':
        rows = 24 * 60 - minutes
    elif tag == 'end':
        rows = minutes
    elif tag == 'full':
        rows = 24 * 60
    else:
        tag = tag.hour * 60 + tag.minute
        rows = tag - minutes
    if not time_bucket:
        return service_dict, rows

    if service_id not in service_dict:
        service_dict[service_id] = np.zeros([rows, (1+len(service_df_head))], float)
        service_dict[service_id][:, 0] = range(rows)
    if tag == 'end':
        service_dict[service_id][time_bucket][1 + index] = value
    else:
        service_dict[service_id][time_bucket-1][1 + index] = value
    return service_dict, rows


def service_utils(service_dict, rows):
    for service in service_dict:      #对每一个service_id
        for index in range(len(service_df_head)):
            for i in range(1, rows):
                if service_dict[service][i, (1+index)] == 0:
                    service_dict[service][i, (1+index)] = service_dict[service][(i-1), (1+index)]
        service_dict[service] = pd.DataFrame(service_dict[service])
        service_dict[service].columns = ['time', 'service_apdex', 'service_resp_time', 'service_sla', 'service_cpm']
        service_dict[service].insert(1, 'service_id', [service]*rows)
        service_dict[service].set_index(keys='time', inplace=True)
    return service_dict


def choice_body(date, tag):
    date = date.strftime("%Y%m%d%H%M")
    if tag == 'full':
        body = {
            'query':{
                'match_all': {}
            }
        }
    elif tag == 'start':
        body = {
            'query': {
                'range': {
                    'time_bucket':
                        {
                            'gt': date
                        }
                }
            }
        }
    elif tag == 'end':
        body = {
            'query': {
                'range': {
                    'time_bucket':
                        {
                            'lte': date
                        }
                }
            }
        }
    else:
        tag = tag.strftime("%Y%m%d%H%M")
        body = {
            'query': {
                'range': {
                    'time_bucket':
                        {
                            'gt': date,
                            'lte': tag
                        }
                }
            }
        }
    return body


def get_service_data(service_dict, index, date, tag):
    d = date.strftime("%Y%m%d")
    file_name = service_df_head[index] + '-' + str(d)
    body = choice_body(date, tag)
    allDoc = es.search(index=file_name, body=body, scroll='5m', size=100)
    results = allDoc['hits']['hits']  # 第一页
    total = allDoc['hits']['total']['value']
    scroll_id = allDoc['_scroll_id']
    rows = None
    for i in range(0, int(total / 100) + 1):
        query_scroll = es.scroll(scroll_id=scroll_id, scroll='5m')['hits']['hits']
        results += query_scroll    #结果全部加载到内存
    for result in results:
        service_dict, rows = get_service_attr(result['_source'], service_dict, index, date, tag)
    return service_dict, rows


def get_service_dict(date, tag='full'):
    service_dict = {}
    for index in range(len(service_df_head)):
        service_dict, rows = get_service_data(service_dict, index, date, tag)
    service_dict = service_utils(service_dict, rows)
    return service_dict


def not_today(days, start_time, now_time):
    dict_list = []
    dls = get_service_dict(start_time, 'start')
    keys = set(dls.keys())
    dict_list.append(dls)
    for day in range(days - 1):
        date = start_time + datetime.timedelta(days=day)
        dl = get_service_dict(date)
        dict_list.append(dl)
        keys.union(set(dl.keys()))
    dle = get_service_dict(now_time, 'end')
    dict_list.append(dle)
    keys.union(set(dle.keys()))
    total_df = pd.DataFrame([])
    for i in iter(keys):
        df = pd.DataFrame([])
        for d in dict_list:
            if i in d.keys():
                df = pd.concat([df, d[i]], ignore_index=True)
        total_df = pd.concat([total_df, df], ignore_index=False)
    # total_df.to_csv('./service_24h.csv', header=True, index=True)
    return total_df, keys


def today(start_time, now_time):
    d = get_service_dict(start_time, now_time)
    keys = set(d.keys())
    df = pd.DataFrame([])
    for i in iter(keys):
        df = pd.concat([df, d[i]], ignore_index=False)
    # df.to_csv('./service_today.csv', header=True, index=True)
    return df, keys


def get_services(ahead_hour, time1):
    # now_time = datetime.datetime.now() + datetime.timedelta(hours=8)  # 现在的时间
    now_time = time1
    # now_date = now_time.strftime("%Y%m%d")  # 获取日期：年、月、日
    # now_minutes = now_time.hour * 60 + now_time.minute  # 当前日期的时间:时*60+分

    start_time = now_time - datetime.timedelta(hours=ahead_hour)  # 开始时间
    # start_date = start_time.strftime("%Y%m%d")  # 开始记录的日期：年、月、日
    # start_minutes = start_time.hour * 60 + now_time.minute  # 开始记录的时间:时*60+分

    days = (now_time-start_time).days
    if days == 0:
        df, keys = today(start_time, now_time)
    else:
        df, keys = not_today(days, start_time, now_time)
    return df, keys


if __name__ == '__main__':
    ahead_hour = 1  # 前多少个小时
    df, keys = get_services(ahead_hour)   #keys:运行过的service
    print(keys)
    # service_id = str(base64.b64decode("bWFzdGVyc2VydmljZWRpcg==".encode('utf-8')), encoding='utf-8')
    # print(service_id)
